﻿// Copyright (c) 2012 - 2020 Jared Zheng <jaredz at outlook dot com>
// Buddha Framework is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//          http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Create : 2012-12-01 version 0.1 Jared Zheng <jaredz at outlook dot com>
// Update : 2018-12-05 version 3.1.5 Jared Zheng <jaredz at outlook dot com>

#include "stdafx.h"
#include "servermap.h"
#include "ServerConsole.h"
#include "BalanceHandler.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// CBalanceHandler
CBalanceHandler::CBalanceHandler(void)
: m_uBalanceAuthor(0)
, m_uBalanceWLAddr(0)
, m_uBalanceLoad(0)
, m_uAuthorCount(0)
, m_uAuthorOnline(0)
, m_uAuthorTotal(0)
{
}

CBalanceHandler::~CBalanceHandler(void)
{
}

void CBalanceHandler::OnLive(bool bStart)
{
    CStringFix strTemp = GetName();
    if (bStart)
    {
        strTemp += TF("Start---");

        CStrAddr strAddr;
        GServerConsoleInst->m_Config.GetServerAddr(CServerConfig::CFG_LOAD_BALANCE, CServerConfig::CFG_LOAD_NONE, strAddr);
        strTemp.AppendFormat(TF("UDP Ext-Listen=[%s]:%d"), *strAddr.strIp, strAddr.usPort);
    }
    else
    {
        strTemp += TF("Stop");

        m_uBalanceAuthor = 0;
        m_uBalanceWLAddr = 0;
        m_uBalanceLoad   = 0;
        m_uAuthorCount   = 0;
        m_uAuthorOnline  = 0;
        m_uAuthorTotal   = 0;
    }
    LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
}

void CBalanceHandler::OnLink(Int nServerIndex, uintptr_t utData)
{
    UNREFERENCED_PARAMETER(nServerIndex);
    assert(nServerIndex == PAKT_CENTER);

    CStringFix strTemp = GetName();

    CNetAddr* pAddr = (reinterpret_cast<CNetAddr*>(utData));

    CStrAddr strAddr;
    GServerConsoleInst->m_Config.GetServerAddr(CServerConfig::CFG_LOAD_CENTER, CServerConfig::CFG_LOAD_NONE, strAddr);
    strTemp.AppendFormat(TF("TCP Int-Connect Center=[%s]:%d"), *strAddr.strIp, strAddr.usPort);

    GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pAddr, false);
    strTemp.AppendFormat(TF("([%s]:%d)"), *strAddr.strIp, strAddr.usPort);

    LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
}

void CBalanceHandler::OnUpdate(Int, uintptr_t)
{
}

void CBalanceHandler::OnSync(Int nServerIndex, uintptr_t utData)
{
    if (nServerIndex == PAKT_AUTHOR)
    {
        PSERVER_STATUS pStatus = reinterpret_cast<PSERVER_STATUS>(utData);
        m_uAuthorTotal  = pStatus->uTotal;
        m_uAuthorOnline = pStatus->uOnline;
        m_uAuthorCount  = pStatus->usLoad;
    }
    else
    {
        PSERVER_STATUS pStatus = reinterpret_cast<PSERVER_STATUS>(utData);
        m_uBalanceAuthor = pStatus->uTotal;
        m_uBalanceWLAddr = pStatus->uOnline;
        m_uBalanceLoad   = pStatus->usLoad / DATAD_TOPERCENT;
    }
}

void CBalanceHandler::OnSync(Int nServerIndex, CStream& Stream)
{
    assert(nServerIndex == PAKT_AUTHOR);

    SVR_AUTHOR_MAP::SVR_PAIR Pair;
    while (Stream.IsEnd() == false)
    {
        Pair.Serialize(Stream);

        if (Pair.Value.usStatus == STATUSU_UNLINK)
        {
            RemoveServerData(nServerIndex, Pair.ullKey);
        }
        else if ((Pair.Value.usStatus == STATUSU_SYNC) || (Pair.Value.usStatus == STATUSU_LINK))
        {
            if (Pair.Value.usStatus == STATUSU_LINK)
            {
                AddServerData(nServerIndex, reinterpret_cast<uintptr_t>(&Pair));
            }
            else
            {
                UpdateServerData(nServerIndex, reinterpret_cast<uintptr_t>(&Pair));
            }
        }
    }
}

void CBalanceHandler::OnUnlink(Int nServerIndex, uintptr_t utData)
{
    UNREFERENCED_PARAMETER(utData);
    if (nServerIndex == PAKT_CENTER)
    {
        m_uAuthorCount  = 0;
        m_uAuthorOnline = 0;
        m_uAuthorTotal  = 0;

        LOG_INFO(GServerConsoleInst->m_FileLog, TF("Balance:TCP Int-Connect Center Closed"));
    }
    else
    {
        assert(nServerIndex == PAKT_BALANCE);
        LOG_INFO(GServerConsoleInst->m_FileLog, TF("Balance:UDP Ext-Listen Closed"));
    }
}

void CBalanceHandler::UpdateServerInfo(void)
{
    CStringFix strTemp = GetName();
    strTemp.Format(TF("[Balance=%u(AuthorAddr)/%u(WLanAddr), Load=%d%%][Author:Count=%u, %u(Linked)/%u(Connected)]"),
                   m_uBalanceAuthor, m_uBalanceWLAddr, m_uBalanceLoad,
                   m_uAuthorCount, m_uAuthorOnline, m_uAuthorTotal);
    LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
}

PCXStr CBalanceHandler::GetName(void)
{
    return TF("Balance:");
}




